home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / unix / tar / part02 < prev    next >
Encoding:
Internet Message Format  |  1990-03-29  |  47.8 KB

  1. Path: xanth!cs.odu.edu!Amiga-Request
  2. From: Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v90i127: tar - tape archive utility, Part02/05
  5. Message-ID: <11980@xanth.cs.odu.edu>
  6. Date: 29 Mar 90 03:09:16 GMT
  7. Sender: tadguy@cs.odu.edu
  8. Reply-To: hue@netcom.uucp (Jonathan Hue)
  9. Lines: 1581
  10. Approved: tadguy@cs.odu.edu (Tad Guy)
  11. X-Mail-Submissions-To: Amiga@cs.odu.edu
  12. X-Post-Discussions-To: comp.sys.amiga
  13.  
  14. Submitted-by: hue@netcom.uucp (Jonathan Hue)
  15. Posting-number: Volume 90, Issue 127
  16. Archive-name: unix/tar/part02
  17.  
  18. #!/bin/sh
  19. # This is a shell archive.  Remove anything before this line, then unpack
  20. # it by saving it into a file and typing "sh file".  To overwrite existing
  21. # files, type "sh file -c".  You can also feed this as standard input via
  22. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  23. # will see the following message at the end:
  24. #        "End of archive 2 (of 5)."
  25. # Contents:  list.c tar.1 tar.5 tar.c
  26. # Wrapped by tadguy@xanth on Wed Mar 28 22:07:12 1990
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'list.c' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'list.c'\"
  30. else
  31. echo shar: Extracting \"'list.c'\" \(12340 characters\)
  32. sed "s/^X//" >'list.c' <<'END_OF_FILE'
  33. X/*
  34. X * List a tar archive.
  35. X *
  36. X * Also includes support routines for reading a tar archive.
  37. X *
  38. X * Pubic Domain version written 26 Aug 1985 by John Gilmore (ihnp4!hoptoad!gnu).
  39. X *
  40. X * @(#)list.c 1.31 11/5/87 Public Domain - gnu
  41. X */
  42. X#include <stdio.h>
  43. X#include <ctype.h>
  44. X#include <sys/types.h>
  45. X#include <sys/stat.h>
  46. X#if !defined(MSDOS) && !defined(AMIGA)
  47. X#include <sys/file.h>
  48. X#endif    /* MSDOS */
  49. X
  50. X#ifdef USG
  51. X#include <sys/sysmacros.h>    /* major() and minor() defined here */
  52. X#endif
  53. X
  54. Xchar *ctime();                /* From libc.a */
  55. X
  56. X#define    isodigit(c)    ( ((c) >= '0') && ((c) <= '7') )
  57. X
  58. X#include "tar.h"
  59. X#include "port.h"
  60. X
  61. X#ifdef AMIGA
  62. Xint made_on_amiga;        /* from extract.c */
  63. X#endif
  64. X
  65. Xlong from_oct();            /* Decode octal number */
  66. Xvoid demode();                /* Print file mode */
  67. X
  68. Xunion record *head;            /* Points to current archive header */
  69. Xstruct stat hstat;            /* Stat struct corresponding */
  70. Xint head_standard;            /* Tape header is in ANSI format */
  71. X
  72. Xvoid print_header();
  73. Xvoid skip_file();
  74. X
  75. X
  76. X/*
  77. X * Main loop for reading an archive.
  78. X */
  79. Xvoid
  80. Xread_and(do_something)
  81. X    void (*do_something)();
  82. X{
  83. X    int status = 3;            /* Initial status at start of archive */
  84. X    int prev_status;
  85. X
  86. X    name_gather();            /* Gather all the names */
  87. X    open_archive(1);        /* Open for reading */
  88. X
  89. X    for(;;) {
  90. X        prev_status = status;
  91. X        status = read_header();
  92. X        switch (status) {
  93. X
  94. X        case 1:            /* Valid header */
  95. X            /* We should decode next field (mode) first... */
  96. X            /* Ensure incoming names are null terminated. */
  97. X            head->header.name[NAMSIZ-1] = '\0';
  98. X            
  99. X            if (!name_match(head->header.name)) {
  100. X                /* Skip past it in the archive */
  101. X                userec(head);
  102. X                /* Skip to the next header on the archive */
  103. X                skip_file((long)hstat.st_size);
  104. X                continue;
  105. X            }
  106. X
  107. X            (*do_something)();
  108. X            continue;
  109. X
  110. X            /*
  111. X             * If the previous header was good, tell them
  112. X             * that we are skipping bad ones.
  113. X             */
  114. X        case 0:            /* Invalid header */
  115. X            userec(head);
  116. X            switch (prev_status) {
  117. X            case 3:        /* Error on first record */
  118. X                annorec(stderr, tar);
  119. X                fprintf(stderr, "Hmm, this doesn't look like a tar archive.\n");
  120. X                /* FALL THRU */
  121. X            case 2:        /* Error after record of zeroes */
  122. X            case 1:        /* Error after header rec */
  123. X                annorec(stderr, tar);
  124. X                fprintf(stderr,
  125. X                    "Skipping to next file header...\n");
  126. X            case 0:        /* Error after error */
  127. X                break;
  128. X            }
  129. X            continue;
  130. X
  131. X        case 2:            /* Record of zeroes */
  132. X            userec(head);
  133. X            status = prev_status;    /* If error after 0's */
  134. X            if (f_ignorez)    
  135. X                continue;
  136. X            /* FALL THRU */
  137. X        case EOF:        /* End of archive */
  138. X            break;
  139. X        }
  140. X        break;
  141. X    };
  142. X
  143. X    close_archive();
  144. X    names_notfound();        /* Print names not found */
  145. X}        
  146. X
  147. X
  148. X/*
  149. X * Print a header record, based on tar options.
  150. X */
  151. Xvoid
  152. Xlist_archive()
  153. X{
  154. X
  155. X    /* Save the record */
  156. X    saverec(&head);
  157. X
  158. X    /* Print the header record */
  159. X    if (f_verbose) {
  160. X        if (f_verbose > 1)
  161. X            decode_header(head, &hstat, &head_standard, 0);
  162. X        print_header(stdout);
  163. X    }
  164. X
  165. X    /* Skip past it in the archive */
  166. X    saverec((union record **) 0);    /* Unsave it */
  167. X    userec(head);
  168. X
  169. X    /* Skip to the next header on the archive */
  170. X    skip_file((long)hstat.st_size);
  171. X}
  172. X
  173. X
  174. X/*
  175. X * Read a record that's supposed to be a header record.
  176. X * Return its address in "head", and if it is good, the file's
  177. X * size in hstat.st_size.
  178. X *
  179. X * Return 1 for success, 0 if the checksum is bad, EOF on eof,
  180. X * 2 for a record full of zeros (EOF marker).
  181. X *
  182. X * You must always userec(head) to skip past the header which this
  183. X * routine reads.
  184. X */
  185. Xint
  186. Xread_header()
  187. X{
  188. X    register int    i;
  189. X    register long    sum, recsum;
  190. X    register char    *p;
  191. X    register union record *header;
  192. X
  193. X    header = findrec();
  194. X    head = header;        /* This is our current header */
  195. X    if (NULL == header) return EOF;
  196. X
  197. X    recsum = from_oct(8,  header->header.chksum);
  198. X
  199. X    sum = 0;
  200. X    p = header->charptr;
  201. X    for (i = sizeof(*header); --i >= 0;) {
  202. X        /*
  203. X         * We can't use unsigned char here because of old compilers,
  204. X         * e.g. V7.
  205. X         */
  206. X        sum += 0xFF & *p++;
  207. X    }
  208. X
  209. X    /* Adjust checksum to count the "chksum" field as blanks. */
  210. X    for (i = sizeof(header->header.chksum); --i >= 0;)
  211. X        sum -= 0xFF & header->header.chksum[i];
  212. X    sum += ' '* sizeof header->header.chksum;    
  213. X
  214. X    if (sum == recsum) {
  215. X        /*
  216. X         * Good record.  Decode file size and return.
  217. X         */
  218. X        if (header->header.linkflag == LF_LINK)
  219. X            hstat.st_size = 0;    /* Links 0 size on tape */
  220. X        else
  221. X            hstat.st_size = from_oct(1+12, header->header.size);
  222. X        return 1;
  223. X    }
  224. X
  225. X    if (sum == 8*' ') {
  226. X        /*
  227. X         * This is a zeroed record...whole record is 0's except
  228. X         * for the 8 blanks we faked for the checksum field.
  229. X         */
  230. X        return 2;
  231. X    }
  232. X
  233. X    return 0;
  234. X}
  235. X
  236. X
  237. X/* 
  238. X * Decode things from a file header record into a "struct stat".
  239. X * Also set "*stdp" to !=0 or ==0 depending whether header record is "Unix
  240. X * Standard" tar format or regular old tar format.
  241. X *
  242. X * read_header() has already decoded the checksum and length, so we don't.
  243. X *
  244. X * If wantug != 0, we want the uid/group info decoded from Unix Standard
  245. X * tapes (for extraction).  If == 0, we are just printing anyway, so save time.
  246. X *
  247. X * decode_header should NOT be called twice for the same record, since the
  248. X * two calls might use different "wantug" values and thus might end up with
  249. X * different uid/gid for the two calls.  If anybody wants the uid/gid they
  250. X * should decode it first, and other callers should decode it without uid/gid
  251. X * before calling a routine, e.g. print_header, that assumes decoded data.
  252. X */
  253. Xdecode_header(header, st, stdp, wantug)
  254. X    register union record    *header;
  255. X    register struct stat    *st;
  256. X    int    *stdp;
  257. X    int    wantug;
  258. X{
  259. X    made_on_amiga = FALSE;
  260. X    st->st_mode = from_oct(8,  header->header.mode);
  261. X    st->st_mtime = from_oct(1+12, header->header.mtime);
  262. X#ifdef AMIGA
  263. X    /*
  264. X     * Tar file made on Amiga, use the prot and comment in header
  265. X     */
  266. X    if (!strcmp("AmigaTar", header->header.magic_cookie))
  267. X    {
  268. X        made_on_amiga = TRUE;
  269. X        st->st_prot = from_hex(header->header.amiga_modes);
  270. X        strcpy(st->st_comment, header->header.comment);
  271. X        st->st_date.ds_Days = from_hex(header->header.ds_Days);
  272. X        st->st_date.ds_Minute = from_hex(header->header.ds_Minute);
  273. X        st->st_date.ds_Tick = from_hex(header->header.ds_Tick);
  274. X    }
  275. X#endif
  276. X    
  277. X    if (0==strcmp(header->header.magic, TMAGIC)) {
  278. X        /* Unix Standard tar archive */
  279. X        *stdp = 1;
  280. X        if (wantug) {
  281. X#ifdef NONAMES
  282. X            st->st_uid = from_oct(8,  header->header.uid);
  283. X            st->st_gid = from_oct(8,  header->header.gid);
  284. X#else
  285. X            st->st_uid = finduid(header->header.uname);
  286. X            st->st_gid = findgid(header->header.gname);
  287. X#endif
  288. X        }
  289. X        switch  (header->header.linkflag) 
  290. X        case LF_BLK: case LF_CHR:
  291. X            st->st_rdev = makedev(from_oct(8, header->header.devmajor),
  292. X                       from_oct(8, header->header.devminor));
  293. X    } else {
  294. X        /* Old fashioned tar archive */
  295. X        *stdp = 0;
  296. X        st->st_uid = from_oct(8,  header->header.uid);
  297. X        st->st_gid = from_oct(8,  header->header.gid);
  298. X        st->st_rdev = 0;
  299. X    }
  300. X}
  301. X
  302. X
  303. X/*
  304. X * Quick and dirty octal conversion.
  305. X *
  306. X * Result is -1 if the field is invalid (all blank, or nonoctal).
  307. X */
  308. Xlong
  309. Xfrom_oct(digs, where)
  310. X    register int    digs;
  311. X    register char    *where;
  312. X{
  313. X    register long    value;
  314. X
  315. X    while (isspace(*where)) {        /* Skip spaces */
  316. X        where++;
  317. X        if (--digs <= 0)
  318. X            return -1;        /* All blank field */
  319. X    }
  320. X    value = 0;
  321. X    while (digs > 0 && isodigit(*where)) {    /* Scan til nonoctal */
  322. X        value = (value << 3) | (*where++ - '0');
  323. X        --digs;
  324. X    }
  325. X
  326. X    if (digs > 0 && *where && !isspace(*where))
  327. X        return -1;            /* Ended on non-space/nul */
  328. X
  329. X    return value;
  330. X}
  331. X
  332. X
  333. X/*
  334. X * Actually print it.
  335. X *
  336. X * Plain and fancy file header block logging.
  337. X * Non-verbose just prints the name, e.g. for "tar t" or "tar x".
  338. X * This should just contain file names, so it can be fed back into tar
  339. X * with xargs or the "-T" option.  The verbose option can give a bunch
  340. X * of info, one line per file.  I doubt anybody tries to parse its
  341. X * format, or if they do, they shouldn't.  Unix tar is pretty random here
  342. X * anyway.
  343. X *
  344. X * Note that print_header uses the globals <head>, <hstat>, and
  345. X * <head_standard>, which must be set up in advance.  This is not very clean
  346. X * and should be cleaned up.  FIXME.
  347. X */
  348. X#define    UGSWIDTH    11        /* min width of User, group, size */
  349. X#define    DATEWIDTH    19        /* Last mod date */
  350. Xstatic int    ugswidth = UGSWIDTH;    /* Max width encountered so far */
  351. X
  352. Xvoid
  353. Xprint_header(outfile)
  354. X    FILE *outfile;
  355. X{
  356. X    char modes[11];
  357. X    char *timestamp;
  358. X    char uform[11], gform[11];    /* These hold formatted ints */
  359. X    char *user, *group;
  360. X    char size[24];        /* Holds a formatted long or maj, min */
  361. X    long longie;        /* To make ctime() call portable */
  362. X    int    pad;
  363. X
  364. X    annofile(outfile, (char *)NULL);
  365. X
  366. X    if (f_verbose <= 1) {
  367. X        /* Just the fax, mam. */
  368. X        fprintf(outfile, "%s\n", head->header.name);
  369. X        return;
  370. X    } else {
  371. X        /* File type and modes */
  372. X        modes[0] = '?';
  373. X        switch (head->header.linkflag) {
  374. X        case LF_NORMAL:
  375. X        case LF_OLDNORMAL:
  376. X        case LF_LINK:
  377. X                modes[0] = '-'; 
  378. X                if ('/' == head->header.name[strlen(head->header.name)-1])
  379. X                    modes[0] = 'd';
  380. X                break;
  381. X        case LF_DIR:    modes[0] = 'd'; break;
  382. X        case LF_SYMLINK:modes[0] = 'l'; break;
  383. X        case LF_BLK:    modes[0] = 'b'; break;
  384. X        case LF_CHR:    modes[0] = 'c'; break;
  385. X        case LF_FIFO:    modes[0] = 'p'; break;    
  386. X        case LF_CONTIG:    modes[0] = 'C'; break;
  387. X        }
  388. X
  389. X        demode((unsigned)hstat.st_mode, modes+1);
  390. X
  391. X        /* Timestamp */
  392. X        longie = hstat.st_mtime;
  393. X        timestamp = ctime(&longie);
  394. X        timestamp[16] = '\0';
  395. X        timestamp[24] = '\0';
  396. X
  397. X        /* User and group names */
  398. X        if (*head->header.uname && head_standard) {
  399. X            user  = head->header.uname;
  400. X        } else {
  401. X            user = uform;
  402. X            (void)sprintf(uform, "%d", (int)hstat.st_uid);
  403. X        }
  404. X        if (*head->header.gname && head_standard) {
  405. X            group = head->header.gname;
  406. X        } else {
  407. X            group = gform;
  408. X            (void)sprintf(gform, "%d", (int)hstat.st_gid);
  409. X        }
  410. X
  411. X        /* Format the file size or major/minor device numbers */
  412. X        switch (head->header.linkflag) {
  413. X        case LF_CHR:
  414. X        case LF_BLK:
  415. X            (void)sprintf(size, "%d,%d",
  416. X                    major(hstat.st_rdev),
  417. X                    minor(hstat.st_rdev));
  418. X            break;
  419. X
  420. X        default:
  421. X            (void)sprintf(size, "%ld", (long)hstat.st_size);
  422. X        }
  423. X
  424. X        /* Figure out padding and print the whole line. */
  425. X        pad = strlen(user) + strlen(group) + strlen(size) + 1;
  426. X        if (pad > ugswidth) ugswidth = pad;
  427. X
  428. X        fprintf(outfile, "%s %s/%s %*s%s %s %s %.*s",
  429. X            modes,
  430. X            user,
  431. X            group,
  432. X            ugswidth - pad,
  433. X            "",
  434. X            size,
  435. X            timestamp+4, timestamp+20,
  436. X            sizeof(head->header.name),
  437. X            head->header.name);
  438. X
  439. X        switch (head->header.linkflag) {
  440. X        case LF_SYMLINK:
  441. X            fprintf(outfile, " -> %s\n", head->header.linkname);
  442. X            break;
  443. X
  444. X        case LF_LINK:
  445. X            fprintf(outfile, " link to %s\n", head->header.linkname);
  446. X            break;
  447. X
  448. X        default:
  449. X            fprintf(outfile, " unknown file type '%c'\n",
  450. X                head->header.linkflag);
  451. X            break;
  452. X
  453. X        case LF_OLDNORMAL:
  454. X        case LF_NORMAL:
  455. X        case LF_CHR:
  456. X        case LF_BLK:
  457. X        case LF_DIR:
  458. X        case LF_FIFO:
  459. X        case LF_CONTIG:
  460. X            putc('\n', outfile);
  461. X            break;
  462. X        }
  463. X    }
  464. X}
  465. X
  466. X/*
  467. X * Print a similar line when we make a directory automatically.
  468. X */
  469. Xvoid
  470. Xpr_mkdir(pathname, length, mode, outfile)
  471. X    char *pathname;
  472. X    int length;
  473. X    int mode;
  474. X    FILE *outfile;
  475. X{
  476. X    char modes[11];
  477. X
  478. X    if (f_verbose > 1) {
  479. X        /* File type and modes */
  480. X        modes[0] = 'd';
  481. X        demode((unsigned)mode, modes+1);
  482. X
  483. X        annofile(outfile, (char *)NULL);
  484. X        fprintf(outfile, "%s %*s %.*s\n",
  485. X            modes,
  486. X            ugswidth+DATEWIDTH,
  487. X            "Creating directory:",
  488. X            length,
  489. X            pathname);
  490. X    }
  491. X}
  492. X
  493. X
  494. X/*
  495. X * Skip over <size> bytes of data in records in the archive.
  496. X */
  497. Xvoid
  498. Xskip_file(size)
  499. X    register long size;
  500. X{
  501. X    union record *x;
  502. X
  503. X    while (size > 0) {
  504. X        x = findrec();
  505. X        if (x == NULL) {    /* Check it... */
  506. X            annorec(stderr, tar);
  507. X            fprintf(stderr, "Unexpected EOF on archive file\n");
  508. X            exit(EX_BADARCH);
  509. X        }
  510. X        userec(x);
  511. X        size -= RECORDSIZE;
  512. X    }
  513. X}
  514. X
  515. X
  516. X/*
  517. X * Decode the mode string from a stat entry into a 9-char string and a null.
  518. X */
  519. Xvoid
  520. Xdemode(mode, string)
  521. X    register unsigned mode;
  522. X    register char *string;
  523. X{
  524. X    register unsigned mask;
  525. X    register char *rwx = "rwxrwxrwx";
  526. X
  527. X    for (mask = 0400; mask != 0; mask >>= 1) {
  528. X        if (mode & mask)
  529. X            *string++ = *rwx++;
  530. X        else {
  531. X            *string++ = '-';
  532. X            rwx++;
  533. X        }
  534. X    }
  535. X
  536. X    if (mode & S_ISUID)
  537. X        if (string[-7] == 'x')
  538. X            string[-7] = 's';
  539. X        else
  540. X            string[-7] = 'S';
  541. X    if (mode & S_ISGID)
  542. X        if (string[-4] == 'x')
  543. X            string[-4] = 's';
  544. X        else
  545. X            string[-4] = 'S';
  546. X    if (mode & S_ISVTX)
  547. X        if (string[-1] == 'x')
  548. X            string[-1] = 't';
  549. X        else
  550. X            string[-1] = 'T';
  551. X    *string = '\0';
  552. X}
  553. X
  554. X#ifdef AMIGA
  555. Xfrom_hex(char *s)
  556. X{
  557. X    int i, val = 0;
  558. X    char nibble;
  559. X
  560. X    for (i = 0; i < 8; i++)
  561. X    {
  562. X    nibble = *s++;
  563. X    nibble = (nibble >= 'a') ? 10 + (nibble - 'a') : nibble - '0';
  564. X    val = (val << 4) + nibble;
  565. X    }
  566. X    return(val);
  567. X}
  568. X#endif
  569. END_OF_FILE
  570. if test 12340 -ne `wc -c <'list.c'`; then
  571.     echo shar: \"'list.c'\" unpacked with wrong size!
  572. fi
  573. # end of 'list.c'
  574. fi
  575. if test -f 'tar.1' -a "${1}" != "-c" ; then 
  576.   echo shar: Will not clobber existing file \"'tar.1'\"
  577. else
  578. echo shar: Extracting \"'tar.1'\" \(10973 characters\)
  579. sed "s/^X//" >'tar.1' <<'END_OF_FILE'
  580. X.TH TAR 1 "5 November 1987"
  581. X.\" @(#)tar.1 1.12 11/6/87 Public Domain - gnu
  582. X.SH NAME
  583. Xtar \- tape (or other media) file archiver
  584. X.SH SYNOPSIS
  585. X\fBtar\fP \-[\fBBcdDhiklmopRstvxzZ\fP]
  586. X[\fB\-b\fP \fIN\fP]
  587. X[\fB\-f\fP \fIF\fP]
  588. X[\fB\-T\fP \fIF\fP]
  589. X[ \fIfilename or regexp\fP\| .\|.\|.  ]
  590. X.SH DESCRIPTION
  591. X\fItar\fP provides a way to store many files into a single archive,
  592. Xwhich can be kept in another Unix file, stored on an I/O device
  593. Xsuch as tape, floppy, cartridge, or disk, sent over a network, or piped to
  594. Xanother program.
  595. XIt is useful for making backup copies, or for packaging up a set of
  596. Xfiles to move them to another system.
  597. X.LP
  598. X\fItar\fP has existed since Version 7 Unix with very little change.
  599. XIt has been proposed as the standard format for interchange of files
  600. Xamong systems that conform to the IEEE P1003 ``Portable Operating System''
  601. Xstandard.
  602. X.LP
  603. XThis version of \fItar\fP supports some of the extensions which
  604. Xwere proposed in the P1003 draft standards, including owner and group
  605. Xnames, and support for named pipes, fifos, contiguous files,
  606. Xand block and character devices.
  607. X.LP
  608. XWhen reading an archive, this version of \fItar\fP continues after
  609. Xfinding an error.  Previous versions required the `i' option to ignore
  610. Xchecksum errors.
  611. X.SH OPTIONS
  612. X\fItar\fP options can be specified in either of two ways.  The usual
  613. XUnix conventions can be used: each option is preceded by `\-'; arguments
  614. Xdirectly follow each option; multiple options can be combined behind one `\-'
  615. Xas long as they take no arguments.  For compatability with the Unix
  616. X\fItar\fP program, the options may also be specified as ``keyletters,''
  617. Xwherein all the option letters occur in the first argument to \fItar\fP,
  618. Xwith no `\-', and their arguments, if any, occur in the second, third, ...
  619. Xarguments.  Examples:
  620. X.LP
  621. XNormal:  tar -f arcname -cv file1 file2
  622. X.LP
  623. XOld:  tar fcv arcname file1 file2
  624. X.LP
  625. XAt least one of the \fB\-c\fP, \fB\-t\fP, \fB-d\fP, or \fB\-x\fP options
  626. Xmust be included.  The rest are optional.
  627. X.LP
  628. XFiles to be operated upon are specified by a list of file names, which
  629. Xfollows the option specifications (or can be read from a file by the
  630. X\fB\-T\fP option).  Specifying a directory name causes that directory
  631. Xand all the files it contains to be (recursively) processed.  If a
  632. Xfull path name is specified when creating an archive, it will be written
  633. Xto the archive without the initial "/", to allow the files to be later
  634. Xread into a different place than where they were
  635. Xdumped from, and a warning will be printed.  If
  636. Xfiles are extracted from an archive which contains 
  637. Xfull path names, they will be extracted relative to the current directory
  638. Xand a warning message printed.
  639. X.LP
  640. XWhen extracting or listing files, the ``file names'' are treated as
  641. Xregular expressions, using mostly the same syntax as the shell.  The
  642. Xshell actually matches each substring between ``/''s separately, while
  643. X\fItar\fP matches the entire string at once, so some anomalies will
  644. Xoccur; e.g. ``*'' or ``?'' can match a ``/''.  To specify a regular
  645. Xexpression as an argument to \fItar\fP, quote it so the shell will not
  646. Xexpand it.
  647. X.IP \fB\-a\fP
  648. XSet the archived bit of the file as it is added to the archive. (Amiga
  649. Xonly)
  650. X.IP \fB\-A\fP
  651. XDo not add the file to the archive if its archived bit is set.
  652. XApplies only to regular files, directories are always dumped
  653. X(Amiga only)
  654. X.IP "\fB\-b\fP \fIN\fP"
  655. XSpecify a blocking factor for the archive.  The block size will be
  656. X\fIN\fP x 512 bytes.  Larger blocks typically run faster and let you
  657. Xfit more data on a tape.  The default blocking factor is set when
  658. X\fItar\fP is compiled, and is typically 20.  There is no limit to the
  659. Xmaximum block size, as long as enough memory can be allocated for it,
  660. Xand as long as the device containing the archive can read or write
  661. Xthat block size.
  662. X.IP \fB\-B\fP
  663. XWhen reading an archive, reblock it as we read it.
  664. XNormally, \fItar\fP reads each
  665. Xblock with a single \fIread(2)\fP system call.  This does not work
  666. Xwhen reading from a pipe or network socket under Berkeley Unix;
  667. X\fIread(2)\fP only gives as much data as has arrived at the moment.
  668. XWith this option, it
  669. Xwill do multiple \fIread(2)\fPs to fill out to a record boundary,
  670. Xrather than reporting an error.
  671. XThis option is default when reading an archive from standard input,
  672. Xor over a network.
  673. X.IP \fB\-c\fP
  674. XCreate an archive from a list of files.
  675. X.IP \fB\-d\fP
  676. XDiff an archive against the files in the file system.  Reports
  677. Xdifferences in file size, mode, uid, gid, and contents.  If a file
  678. Xexists on the tape, but not in the file system, that is reported.
  679. XThis option needs further work to be really useful.
  680. X.IP \fB\-D\fP
  681. XWhen creating an archive, only dump each directory itself; don't dump
  682. Xall the files inside the directory.  In conjunction with \fIfind\fP(1),
  683. Xthis is useful in creating incremental dumps for archival backups,
  684. Xsimilar to those produced by \fIdump\fP(8).
  685. X.IP "\fB\-f\fP \fIF\fP"
  686. XSpecify the filename of the archive.  If the specified filename is ``\-'',
  687. Xthe archive is read from the standard input or written to the standard output.
  688. XIf the \fB-f\fP option is not used, and the environment variable \fBTAPE\fP
  689. Xexists, its value will be used; otherwise,
  690. Xa default archive name (which was picked when tar was compiled) is used.
  691. XThe default is normally set to the ``first'' tape drive or other transportable
  692. XI/O medium on the system.
  693. X.IP
  694. XIf the filename contains a colon before a slash, it is interpreted
  695. Xas a ``hostname:/file/name'' pair.  \fItar\fP will invoke the commands
  696. X\fIrsh\fP and \fIdd\fP to access the specified file or device on the
  697. Xsystem \fIhostname\fP.  If you need to do something unusual like rsh with
  698. Xa different user name, use ``\fB\-f \-\fP'' and pipe it to rsh manually.
  699. X.IP \fB\-h\fP
  700. XWhen creating an archive, if a symbolic link is encountered, dump
  701. Xthe file or directory to which it points, rather than
  702. Xdumping it as a symbolic link.  (Does not apply to Amiga)
  703. X.IP \fB\-i\fP
  704. XWhen reading an archive, ignore blocks of zeros in the archive.  Normally
  705. Xa block of zeros indicates the end of the archive,
  706. Xbut in a damaged archive, or one which was
  707. Xcreated by appending several archives, this option allows \fItar\fP to 
  708. Xcontinue.  It is not on by default because there is garbage written after the
  709. Xzeroed blocks by the Unix \fItar\fP program.  Note that with this option
  710. Xset, \fItar\fP will read all the way to the end of the file, eliminating
  711. Xproblems with multi-file tapes.
  712. X.IP \fB\-k\fP
  713. XWhen extracting files from an archive, keep existing files, rather than
  714. Xoverwriting them with the version from the archive.
  715. X.IP \fB\-l\fP
  716. XWhen dumping the contents of a directory to an archive, stay within the
  717. Xlocal file system of that directory.  This option
  718. Xonly affects the files dumped because
  719. Xthey are in a dumped directory; files named on the command line are
  720. Xalways dumped, and they can be from various file systems.
  721. XThis is useful for making ``full dump'' archival backups of a file system,
  722. Xas with the \fIdump\fP(8) command.  Files which are skipped due to this
  723. Xoption are mentioned on the standard error.
  724. X.IP \fB\-m\fP
  725. XWhen extracting files from an archive, set each file's modified timestamp
  726. Xto the current time, rather than extracting each file's modified
  727. Xtimestamp from the archive.
  728. X.IP \fB\-o\fP
  729. XWhen creating an archive, write an old format archive, which does not
  730. Xinclude information about directories, pipes, fifos, 
  731. Xcontiguous files, or device files, and 
  732. Xspecifies file ownership by uid's and gid's rather than by
  733. Xuser names and group names.  In most cases, a ``new'' format archive
  734. Xcan be read by an ``old'' tar program without serious trouble, so this
  735. Xoption should seldom be needed.
  736. X.IP \fB\-p\fP
  737. XWhen extracting files from an archive, restore them to the same permissions
  738. Xthat they had in the archive.  If \fB\-p\fP is not specified, the current
  739. Xumask limits the permissions of the extracted files.  See \fIumask(2)\fP.
  740. X(Does not apply to Amiga version, permission always completely restored)
  741. X.IP \fB\-R\fP
  742. XWith each message that \fItar\fP produces, print the record number
  743. Xwithin the archive where the message occurred.  This option is especially
  744. Xuseful when reading damaged archives, since it helps to pinpoint the damaged
  745. Xsection.
  746. X.IP \fB\-s\fP
  747. XWhen specifying a list of filenames to be listed
  748. Xor extracted from an archive,
  749. Xthe \fB\-s\fP flag specifies that the list
  750. Xis sorted into the same order as the tape.  This allows a large list
  751. Xto be used, even on small machines, because
  752. Xthe entire list need not be read into memory at once.  Such a sorted
  753. Xlist can easily be created by running ``tar \-t'' on the archive and
  754. Xediting its output.
  755. X.IP \fB\-t\fP
  756. XList a table of contents of an existing archive.  If file names are
  757. Xspecified, just list files matching the specified names.  The listing
  758. Xappears on the standard output.
  759. X.IP "\fB\-T\fP \fIF\fP"
  760. XRather than specifying file names or regular expressions as arguments to
  761. Xthe \fItar\fP command, this option specifies that they should
  762. Xbe read from the file \fIF\fP, one per line.
  763. XIf the file name specified is ``\-'',
  764. Xthe list is read from the standard input.
  765. XThis option, in conjunction with the \fB\-s\fP option,
  766. Xallows an arbitrarily large list of files to be processed, 
  767. Xand allows the list to be piped to \fItar\fP.
  768. X.IP \fB\-v\fP
  769. XBe verbose about the files that are being processed or listed.  Normally,
  770. Xarchive creation, file extraction, and differencing are silent,
  771. Xand archive listing just
  772. Xgives file names.  The \fB\-v\fP option causes an ``ls \-l''\-like listing
  773. Xto be produced.  The output from -v appears on the standard output except
  774. Xwhen creating an archive (since the new archive might be on standard output),
  775. Xwhere it goes to the standard error output.
  776. X.IP \fB\-x\fP
  777. XExtract files from an existing archive.  If file names are
  778. Xspecified, just extract files matching the specified names, otherwise extract
  779. Xall the files in the archive.
  780. X.IP "\fB\-z\fP or \fB\-Z\fP"
  781. XThe archive should be compressed as it is written, or decompressed as it
  782. Xis read, using the \fIcompress(1)\fP program.  This option works on I/O
  783. Xdevices and over the network, as well as on disk files; data to or from
  784. Xsuch devices is reblocked using a ``dd'' command
  785. Xto enforce the specified (or default) block size.  The default compression
  786. Xparameters are used; if you need to override them, avoid the ``z'' option
  787. Xand compress it yourself.  (Not currently supported on Amiga)
  788. X.SH "SEE ALSO"
  789. Xshar(1), tar(5), compress(1), ar(1), arc(1), cpio(1), dump(8), restore(8),
  790. Xrestor(8), rsh(1), dd(1), find(1)
  791. X.SH BUGS
  792. XThe \fBr, u, w, X, l, F, C\fP, and \fIdigit\fP options of Unix \fItar\fP
  793. Xare not supported.
  794. X.LP
  795. XMultiple-tape (or floppy) archives should be supported, but so far no
  796. Xclean way has been implemented.
  797. X.LP
  798. XA bug in the Bourne Shell usually causes an extra newline to be written
  799. Xto the standard error when using compressed or remote archives.
  800. X.LP
  801. XA bug in ``dd'' prevents turning off the ``x+y records in/out'' messages
  802. Xon the standard error when ``dd'' is used to reblock or transport an archive.
  803. END_OF_FILE
  804. if test 10973 -ne `wc -c <'tar.1'`; then
  805.     echo shar: \"'tar.1'\" unpacked with wrong size!
  806. fi
  807. # end of 'tar.1'
  808. fi
  809. if test -f 'tar.5' -a "${1}" != "-c" ; then 
  810.   echo shar: Will not clobber existing file \"'tar.5'\"
  811. else
  812. echo shar: Extracting \"'tar.5'\" \(9253 characters\)
  813. sed "s/^X//" >'tar.5' <<'END_OF_FILE'
  814. X.TH TAR 5 "15 October 1987"
  815. X.\" @(#)tar.5 1.4 11/6/87 Public Domain - gnu
  816. X.SH NAME
  817. Xtar \- tape (or other media) archive file format
  818. X.SH DESCRIPTION
  819. XA ``tar tape'' or file contains a series of records.  Each record contains
  820. XTRECORDSIZE bytes (see below).  Although this format may be thought of as
  821. Xbeing on magnetic tape, other media are often used.
  822. XEach file archived is represented by a header record
  823. Xwhich describes the file, followed by zero or more records which give the
  824. Xcontents of the file.  At the end of the archive file there may be a record
  825. Xfilled with binary zeros as an end-of-file indicator.  A reasonable
  826. Xsystem should write a record of zeros at the end, but must not assume that
  827. Xan end-of-file record exists when reading an archive.
  828. X
  829. XThe records may be blocked for physical I/O operations.  Each block of
  830. X\fIN\fP records (where \fIN\fP is set by the \fB\-b\fP option to \fItar\fP)
  831. Xis written with a single write() operation.  On
  832. Xmagnetic tapes, the result of such a write is a single tape record.
  833. XWhen writing an archive, the last block of records should be written
  834. Xat the full size, with records after the zero record containing
  835. Xall zeroes.  When reading an archive, a reasonable system should
  836. Xproperly handle an archive whose last block is shorter than the rest, or
  837. Xwhich contains garbage records after a zero record.
  838. X
  839. XThe header record is defined in the header file <tar.h> as follows:
  840. X.nf
  841. X.sp .5v
  842. X.DT
  843. X/*
  844. X * Standard Archive Format - Standard TAR - USTAR
  845. X */
  846. X#define    RECORDSIZE    512
  847. X#define    NAMSIZ    100
  848. X#define    TUNMLEN    32
  849. X#define    TGNMLEN    32
  850. X
  851. Xunion record {
  852. X    char        charptr[RECORDSIZE];
  853. X    struct header {
  854. X        char    name[NAMSIZ];
  855. X        char    mode[8];
  856. X        char    uid[8];
  857. X        char    gid[8];
  858. X        char    size[12];
  859. X        char    mtime[12];
  860. X        char    chksum[8];
  861. X        char    linkflag;
  862. X        char    linkname[NAMSIZ];
  863. X        char    magic[8];
  864. X        char    uname[TUNMLEN];
  865. X        char    gname[TGNMLEN];
  866. X        char    devmajor[8];
  867. X        char    devminor[8];
  868. X    } header;
  869. X};
  870. X
  871. X/* The checksum field is filled with this while the checksum is computed. */
  872. X#define    CHKBLANKS    "        "        /* 8 blanks, no null */
  873. X
  874. X/* The magic field is filled with this if uname and gname are valid. */
  875. X#define    TMAGIC    "ustar  "        /* 7 chars and a null */
  876. X
  877. X/* The linkflag defines the type of file */
  878. X#define    LF_OLDNORMAL '\\0'        /* Normal disk file, Unix compatible */
  879. X#define    LF_NORMAL    '0'        /* Normal disk file */
  880. X#define    LF_LINK    '1'        /* Link to previously dumped file */
  881. X#define    LF_SYMLINK    '2'        /* Symbolic link */
  882. X#define    LF_CHR    '3'        /* Character special file */
  883. X#define    LF_BLK    '4'        /* Block special file */
  884. X#define    LF_DIR        '5'        /* Directory */
  885. X#define    LF_FIFO    '6'        /* FIFO special file */
  886. X#define    LF_CONTIG    '7'        /* Contiguous file */
  887. X/* Further link types may be defined later. */
  888. X
  889. X/* Bits used in the mode field - values in octal */
  890. X#define    TSUID        04000        /* Set UID on execution */
  891. X#define    TSGID        02000        /* Set GID on execution */
  892. X#define    TSVTX        01000        /* Save text (sticky bit) */
  893. X
  894. X/* File permissions */
  895. X#define    TUREAD    00400        /* read by owner */
  896. X#define    TUWRITE    00200        /* write by owner */
  897. X#define    TUEXEC    00100        /* execute/search by owner */
  898. X#define    TGREAD    00040        /* read by group */
  899. X#define    TGWRITE    00020        /* write by group */
  900. X#define    TGEXEC    00010        /* execute/search by group */
  901. X#define    TOREAD    00004        /* read by other */
  902. X#define    TOWRITE    00002        /* write by other */
  903. X#define    TOEXEC    00001        /* execute/search by other */
  904. X.fi
  905. X.LP
  906. XAll characters in header records
  907. Xare represented using 8-bit characters in the local
  908. Xvariant of ASCII.
  909. XEach field within the structure is contiguous; that is, there is
  910. Xno padding used within the structure.  Each character on the archive medium
  911. Xis stored contiguously.
  912. X
  913. XBytes representing the contents of files (after the header record
  914. Xof each file) are not translated in any way and
  915. Xare not constrained to represent characters or to be in any character set.
  916. XThe \fItar\fP(5) format does not distinguish text files from binary
  917. Xfiles, and no translation of file contents should be performed.
  918. X
  919. XThe fields \fIname, linkname, magic, uname\fP, and \fIgname\fP are
  920. Xnull-terminated
  921. Xcharacter strings.  All other fields are zero-filled octal numbers in
  922. XASCII.  Each numeric field (of width \fIw\fP) contains \fIw\fP-2 digits, a space, and
  923. Xa null, except \fIsize\fP and \fImtime\fP,
  924. Xwhich do not contain the trailing null.
  925. X
  926. XThe \fIname\fP field is the pathname of the file, with directory names
  927. X(if any) preceding the file name, separated by slashes.
  928. X
  929. XThe \fImode\fP field provides nine bits specifying file permissions and three
  930. Xbits to specify the Set UID, Set GID and Save Text (TSVTX) modes.  Values
  931. Xfor these bits are defined above.  When special permissions are required
  932. Xto create a file with a given mode, and the user restoring files from the
  933. Xarchive does not hold such permissions, the mode bit(s) specifying those
  934. Xspecial permissions are ignored.  Modes which are not supported by the
  935. Xoperating system restoring files from the archive will be ignored.
  936. XUnsupported modes should be faked up when creating an archive; e.g.
  937. Xthe group permission could be copied from the `other' permission.
  938. X
  939. XThe \fIuid\fP and \fIgid\fP fields are the user and group ID of the file owners,
  940. Xrespectively.
  941. X
  942. XThe \fIsize\fP field is the size of the file in bytes; linked files are archived
  943. Xwith this field specified as zero.
  944. X
  945. XThe \fImtime\fP field is the modification time of the file at the time it was
  946. Xarchived.  It is the ASCII representation of the octal value of the
  947. Xlast time the file was modified, represented as in integer number of
  948. Xseconds since January 1, 1970, 00:00 Coordinated Universal Time.
  949. X
  950. XThe \fIchksum\fP field is the ASCII representaion of the octal value of the
  951. Xsimple sum of all bytes in the header record.  Each 8-bit byte in the
  952. Xheader is treated as an unsigned value.  These values are added to an
  953. Xunsigned integer, initialized to zero, the precision of which shall be no
  954. Xless than seventeen bits.  When calculating the checksum, the \fIchksum\fP
  955. Xfield is treated as if it were all blanks.
  956. X
  957. XThe \fItypeflag\fP field specifies the type of file archived.  If a particular
  958. Ximplementation does not recognize or permit the specified type, the file
  959. Xwill be extracted as if it were a regular file.  As this action occurs,
  960. X\fItar\fP issues a warning to the standard error.
  961. X.IP "LF_NORMAL or LF_OLDNORMAL"
  962. Xrepresents a regular file.
  963. XFor backward compatibility, a \fItypeflag\fP value of LF_OLDNORMAL
  964. Xshould be silently recognized as a regular file.  New archives should
  965. Xbe created using LF_NORMAL.
  966. XAlso, for backward
  967. Xcompatability, \fItar\fP treats a regular file whose name ends
  968. Xwith a slash as a directory.
  969. X.IP LF_LINK
  970. Xrepresents a file linked to another file, of any type,
  971. Xpreviously archived.  Such files are identified in Unix by each file
  972. Xhaving the same device and inode number.  The linked-to
  973. Xname is specified in the \fIlinkname\fP field with a trailing null.
  974. X.IP LF_SYMLINK
  975. Xrepresents a symbolic link to another file.  The linked-to
  976. Xname is specified in the \fIlinkname\fP field with a trailing null.
  977. X.IP "LF_CHR or LF_BLK"
  978. Xrepresent character special files and block
  979. Xspecial files respectively.
  980. XIn this case the \fIdevmajor\fP and \fIdevminor\fP
  981. Xfields will contain the
  982. Xmajor and minor device numbers respectively.  Operating
  983. Xsystems may map the device specifications to their own local
  984. Xspecification, or may ignore the entry.
  985. X.IP LF_DIR
  986. Xspecifies a directory or sub-directory.  The directory name
  987. Xin the \fIname\fP field should end with a slash.
  988. XOn systems where
  989. Xdisk allocation is performed on a directory basis the \fIsize\fP
  990. Xfield will contain the maximum number of bytes (which may be
  991. Xrounded to the nearest disk block allocation unit) which the
  992. Xdirectory may hold.  A \fIsize\fP field of zero indicates no such
  993. Xlimiting.  Systems which do not support limiting in this
  994. Xmanner should ignore the \fIsize\fP field.
  995. X.IP LF_FIFO
  996. Xspecifies a FIFO special file.  Note that the archiving of
  997. Xa FIFO file archives the existence of this file and not its
  998. Xcontents.
  999. X.IP LF_CONTIG
  1000. Xspecifies a contiguous file, which is the same as a normal
  1001. Xfile except that, in operating systems which support it,
  1002. Xall its space is allocated contiguously on the disk.  Operating
  1003. Xsystems which do not allow contiguous allocation should silently treat
  1004. Xthis type as a normal file.
  1005. X.IP "`A' \- `Z'"
  1006. Xare reserved for custom implementations.  None are used by this
  1007. Xversion of the \fItar\fP program.
  1008. X.IP \fIother\fP
  1009. Xvalues are reserved for specification in future revisions of the
  1010. XP1003 standard, and should not be used by any \fItar\fP program.
  1011. X.LP
  1012. XThe \fImagic\fP field indicates that this archive was output in the P1003
  1013. Xarchive format.  If this field contains TMAGIC, then the
  1014. X\fIuname\fP and \fIgname\fP
  1015. Xfields will contain the ASCII representation of the owner and group of the
  1016. Xfile respectively.  If found, the user and group ID represented by these
  1017. Xnames
  1018. Xwill be used rather than the values contained
  1019. Xwithin the \fIuid\fP and \fIgid\fP fields.
  1020. XUser names longer than TUNMLEN-1 or group
  1021. Xnames longer than TGNMLEN-1 characters will be truncated.
  1022. X.SH "SEE ALSO"
  1023. Xtar(1), ar(5), cpio(5), dump(8), restor(8), restore(8)
  1024. X.SH BUGS
  1025. XNames or link names longer than NAMSIZ-1 characters cannot be archived.
  1026. X
  1027. XThis format does not yet address multi-volume archives.
  1028. X.SH NOTES
  1029. XThis manual page was adapted by John Gilmore
  1030. Xfrom Draft 6 of the P1003 specification
  1031. END_OF_FILE
  1032. if test 9253 -ne `wc -c <'tar.5'`; then
  1033.     echo shar: \"'tar.5'\" unpacked with wrong size!
  1034. fi
  1035. # end of 'tar.5'
  1036. fi
  1037. if test -f 'tar.c' -a "${1}" != "-c" ; then 
  1038.   echo shar: Will not clobber existing file \"'tar.c'\"
  1039. else
  1040. echo shar: Extracting \"'tar.c'\" \(11897 characters\)
  1041. sed "s/^X//" >'tar.c' <<'END_OF_FILE'
  1042. X/*
  1043. X * A public domain tar(1) program.
  1044. X * 
  1045. X * Written by John Gilmore, ihnp4!hoptoad!gnu, starting 25 Aug 85.
  1046. X *
  1047. X * @(#)tar.c 1.34 11/6/87 Public Domain - gnu
  1048. X */
  1049. X
  1050. X#include <stdio.h>
  1051. X#include <sys/types.h>        /* Needed for typedefs in tar.h */
  1052. X
  1053. Xextern char     *malloc();
  1054. Xextern char     *getenv();
  1055. Xextern char    *strncpy();
  1056. Xextern char    *optarg;    /* Pointer to argument */
  1057. Xextern int    optind;        /* Global argv index from getopt */
  1058. X
  1059. X/*
  1060. X * The following causes "tar.h" to produce definitions of all the
  1061. X * global variables, rather than just "extern" declarations of them.
  1062. X */
  1063. X#define TAR_EXTERN /**/
  1064. X#include "tar.h"
  1065. X
  1066. X/*
  1067. X * We should use a conversion routine that does reasonable error
  1068. X * checking -- atoi doesn't.  For now, punt.  FIXME.
  1069. X */
  1070. X#define intconv    atoi
  1071. Xextern int    getoldopt();
  1072. Xextern void    read_and();
  1073. Xextern void    list_archive();
  1074. Xextern void    extract_archive();
  1075. Xextern void    diff_archive();
  1076. Xextern void    create_archive();
  1077. X
  1078. Xstatic FILE    *namef;        /* File to read names from */
  1079. Xstatic char    **n_argv;    /* Argv used by name routines */
  1080. Xstatic int    n_argc;    /* Argc used by name routines */
  1081. X                /* They also use "optind" from getopt(). */
  1082. X
  1083. Xvoid    describe();
  1084. X
  1085. X#ifdef AMIGA
  1086. Xextern char *_TZ;        /* timezone stuff */
  1087. X#endif
  1088. X
  1089. X/*
  1090. X * Main routine for tar.
  1091. X */
  1092. Xmain(argc, argv)
  1093. X    int    argc;
  1094. X    char    **argv;
  1095. X{
  1096. X
  1097. X    /* Uncomment this message in particularly buggy versions...
  1098. X    fprintf(stderr,
  1099. X     "tar: You are running an experimental PD tar, maybe use /bin/tar.\n");
  1100. X     */
  1101. X
  1102. X    tar = "tar";        /* Set program name */
  1103. X
  1104. X    options(argc, argv);
  1105. X
  1106. X    name_init(argc, argv);
  1107. X
  1108. X    if (f_create) {
  1109. X        if (f_extract || f_list || f_diff) goto dupflags;
  1110. X        create_archive();
  1111. X    } else if (f_extract) {
  1112. X        if (f_list || f_diff) goto dupflags;
  1113. X        extr_init();
  1114. X        read_and(extract_archive);
  1115. X    } else if (f_list) {
  1116. X        if (f_diff) goto dupflags;
  1117. X        read_and(list_archive);
  1118. X    } else if (f_diff) {
  1119. X        diff_init();
  1120. X        read_and(diff_archive);
  1121. X    } else {
  1122. Xdupflags:
  1123. X        fprintf (stderr,
  1124. X"tar: you must specify exactly one of the c, t, x, or d options\n");
  1125. X        describe();
  1126. X        exit(EX_ARGSBAD);
  1127. X    }
  1128. X    exit(0);
  1129. X    /* NOTREACHED */
  1130. X}
  1131. X
  1132. X
  1133. X/*
  1134. X * Parse the options for tar.
  1135. X */
  1136. Xint
  1137. Xoptions(argc, argv)
  1138. X    int    argc;
  1139. X    char    **argv;
  1140. X{
  1141. X    register int    c;        /* Option letter */
  1142. X#ifdef AMIGA
  1143. X    char *timezone;
  1144. X#endif
  1145. X
  1146. X    /* Set default option values */
  1147. X    blocking = DEFBLOCKING;        /* From Makefile */
  1148. X    ar_file = getenv("TAPE");    /* From environment, or */
  1149. X#ifdef AMIGA
  1150. X    timezone = getenv("TZ");
  1151. X    if (timezone)
  1152. X    {
  1153. X        _TZ = malloc(strlen(timezone) + 1);    /* man page unclear about */
  1154. X        strcpy(_TZ, timezone);        /* whether this is needed */
  1155. X        free(timezone);
  1156. X    }
  1157. X    else
  1158. X        _TZ = "CST6CDT";
  1159. X    tzset();
  1160. X#endif
  1161. X    if (ar_file == 0)
  1162. X#ifdef AMIGA
  1163. X        ar_file = "ram:tarfile";    /* From Makefile */
  1164. X#else
  1165. X        ar_file = DEF_AR_FILE;    /* From Makefile */
  1166. X#endif
  1167. X    /* Parse options */
  1168. X#ifdef AMIGA
  1169. X    while ((c = getoldopt(argc, argv, "aAb:BcdDf:hiklmopRstT:vxzZ")
  1170. X#else
  1171. X    while ((c = getoldopt(argc, argv, "b:BcdDf:hiklmopRstT:vxzZ")
  1172. X#endif
  1173. X        ) != EOF) {
  1174. X        switch (c) {
  1175. X
  1176. X#ifdef AMIGA
  1177. X        case 'a':
  1178. X            f_archive_set++;
  1179. X            break;
  1180. X
  1181. X        case 'A':
  1182. X            f_archive_check++;
  1183. X            break;
  1184. X#endif
  1185. X
  1186. X        case 'b':
  1187. X            blocking = intconv(optarg);
  1188. X            break;
  1189. X
  1190. X        case 'B':
  1191. X            f_reblock++;        /* For reading 4.2BSD pipes */
  1192. X            break;
  1193. X
  1194. X        case 'c':
  1195. X            f_create++;
  1196. X            break;
  1197. X
  1198. X        case 'd':
  1199. X            f_diff++;        /* Find difference tape/disk */
  1200. X            break;
  1201. X
  1202. X        case 'D':
  1203. X            f_dironly++;        /* Dump dir, not contents */
  1204. X            break;
  1205. X
  1206. X        case 'f':
  1207. X            ar_file = optarg;
  1208. X            break;
  1209. X
  1210. X        case 'h':
  1211. X            f_follow_links++;    /* follow symbolic links */
  1212. X            break;
  1213. X
  1214. X        case 'i':
  1215. X            f_ignorez++;        /* Ignore zero records (eofs) */
  1216. X            /*
  1217. X             * This can't be the default, because Unix tar
  1218. X             * writes two records of zeros, then pads out the
  1219. X             * block with garbage.
  1220. X             */
  1221. X            break;
  1222. X
  1223. X        case 'k':            /* Don't overwrite files */
  1224. X#ifdef NO_OPEN3
  1225. X            fprintf(stderr,
  1226. X                "tar: can't do -k option on this system\n");
  1227. X            exit(EX_ARGSBAD);
  1228. X#else
  1229. X            f_keep++;
  1230. X#endif
  1231. X            break;
  1232. X
  1233. X        case 'l':
  1234. X            f_local_filesys++;
  1235. X            break;
  1236. X
  1237. X        case 'm':
  1238. X            f_modified++;
  1239. X            break;
  1240. X
  1241. X        case 'o':            /* Generate old archive */
  1242. X            f_oldarch++;
  1243. X            break;
  1244. X
  1245. X        case 'p':
  1246. X            f_use_protection++;
  1247. X            break;
  1248. X
  1249. X        case 'R':
  1250. X            f_sayblock++;        /* Print block #s for debug */
  1251. X            break;            /* of bad tar archives */
  1252. X
  1253. X        case 's':
  1254. X            f_sorted_names++;    /* Names to extr are sorted */
  1255. X            break;
  1256. X
  1257. X        case 't':
  1258. X            f_list++;
  1259. X            f_verbose++;        /* "t" output == "cv" or "xv" */
  1260. X            break;
  1261. X
  1262. X        case 'T':
  1263. X            name_file = optarg;
  1264. X            f_namefile++;
  1265. X            break;
  1266. X
  1267. X        case 'v':
  1268. X            f_verbose++;
  1269. X            break;
  1270. X
  1271. X        case 'x':
  1272. X            f_extract++;
  1273. X            break;
  1274. X
  1275. X        case 'z':        /* Easy to type */
  1276. X        case 'Z':        /* Like the filename extension .Z */
  1277. X            f_compress++;
  1278. X            break;
  1279. X
  1280. X        case '?':
  1281. X            describe();
  1282. X            exit(EX_ARGSBAD);
  1283. X
  1284. X        }
  1285. X    }
  1286. X
  1287. X    blocksize = blocking * RECORDSIZE;
  1288. X}
  1289. X
  1290. X
  1291. X/* 
  1292. X * Print as much help as the user's gonna get.
  1293. X *
  1294. X * We have to sprinkle in the KLUDGE lines because too many compilers
  1295. X * cannot handle character strings longer than about 512 bytes.  Yuk!
  1296. X * In particular, MSDOS MSC 4.0 (and 5.0) and PDP-11 V7 Unix have this
  1297. X * problem.
  1298. X */
  1299. Xvoid
  1300. Xdescribe()
  1301. X{
  1302. X    /* sorry, can't #ifdef AMIGA inside string */
  1303. X    fputs("\
  1304. Xtar: valid options:\n\
  1305. X-a    set the archived bit of each file as it's added to the archive\n\
  1306. X-b N    blocking factor N (block size = Nx512 bytes)\n\
  1307. X-B    reblock as we read (for reading 4.2BSD pipes)\n\
  1308. X-c    create an archive\n\
  1309. X-d    find differences between archive and file system\n\
  1310. X-D    don't dump the contents of directories, just the directory\n\
  1311. X", stderr); /* KLUDGE */ fputs("\
  1312. X-f F    read/write archive from file or device F (or hostname:/ForD)\n\
  1313. X-h    don't dump symbolic links; dump the files they point to\n\
  1314. X-i    ignore blocks of zeros in the archive, which normally mean EOF\n\
  1315. X-k    keep existing files, don't overwrite them from the archive\n\
  1316. X-l    stay in the local file system (like dump(8)) when creating an archive\n\
  1317. X", stderr); /* KLUDGE */ fputs("\
  1318. X-m    don't extract file modified time\n\
  1319. X-o    write an old V7 format archive, rather than ANSI [draft 6] format\n\
  1320. X-p    do extract all protection information\n\
  1321. X-R    dump record number within archive with each message\n\
  1322. X-s    list of names to extract is sorted to match the archive\n\
  1323. X-t    list a table of contents of an archive\n\
  1324. X", stderr); /* KLUDGE */ fputs("\
  1325. X-T F    get names to extract or create from file F\n\
  1326. X-v    verbosely list what files we process\n\
  1327. X-x    extract files from an archive\n\
  1328. X-z or Z    run the archive through compress(1)\n\
  1329. X", stderr);
  1330. X}
  1331. X
  1332. X
  1333. X/*
  1334. X * Set up to gather file names for tar.
  1335. X *
  1336. X * They can either come from stdin or from argv.
  1337. X */
  1338. Xname_init(argc, argv)
  1339. X    int    argc;
  1340. X    char    **argv;
  1341. X{
  1342. X
  1343. X    if (f_namefile) {
  1344. X        if (optind < argc) {
  1345. X            fprintf(stderr, "tar: too many args with -T option\n");
  1346. X            exit(EX_ARGSBAD);
  1347. X        }
  1348. X        if (!strcmp(name_file, "-")) {
  1349. X            namef = stdin;
  1350. X        } else {
  1351. X            namef = fopen(name_file, "r");
  1352. X            if (namef == NULL) {
  1353. X                fprintf(stderr, "tar: ");
  1354. X                perror(name_file);
  1355. X                exit(EX_BADFILE);
  1356. X            }
  1357. X        }
  1358. X    } else {
  1359. X        /* Get file names from argv, after options. */
  1360. X        n_argc = argc;
  1361. X        n_argv = argv;
  1362. X    }
  1363. X}
  1364. X
  1365. X/*
  1366. X * Get the next name from argv or the name file.
  1367. X *
  1368. X * Result is in static storage and can't be relied upon across two calls.
  1369. X */
  1370. Xchar *
  1371. Xname_next()
  1372. X{
  1373. X    static char    buffer[NAMSIZ+2];    /* Holding pattern */
  1374. X    register char    *p;
  1375. X    register char    *q;
  1376. X
  1377. X    if (namef == NULL) {
  1378. X        /* Names come from argv, after options */
  1379. X        if (optind < n_argc)
  1380. X            return n_argv[optind++];
  1381. X        return (char *)NULL;
  1382. X    }
  1383. X    for (;;) {
  1384. X        p = fgets(buffer, NAMSIZ+1 /*nl*/, namef);
  1385. X        if (p == NULL) return p;    /* End of file */
  1386. X        q = p+strlen(p)-1;        /* Find the newline */
  1387. X        if (q <= p) continue;        /* Ignore empty lines */
  1388. X        *q-- = '\0';            /* Zap the newline */
  1389. X        while (q > p && *q == '/')  *q-- = '\0'; /* Zap trailing /s */
  1390. X        return p;
  1391. X    }
  1392. X    /* NOTREACHED */
  1393. X}
  1394. X
  1395. X
  1396. X/*
  1397. X * Close the name file, if any.
  1398. X */
  1399. Xname_close()
  1400. X{
  1401. X
  1402. X    if (namef != NULL && namef != stdin) fclose(namef);
  1403. X}
  1404. X
  1405. X
  1406. X/*
  1407. X * Gather names in a list for scanning.
  1408. X * Could hash them later if we really care.
  1409. X *
  1410. X * If the names are already sorted to match the archive, we just
  1411. X * read them one by one.  name_gather reads the first one, and it
  1412. X * is called by name_match as appropriate to read the next ones.
  1413. X * At EOF, the last name read is just left in the buffer.
  1414. X * This option lets users of small machines extract an arbitrary
  1415. X * number of files by doing "tar t" and editing down the list of files.
  1416. X */
  1417. Xname_gather()
  1418. X{
  1419. X    register char *p;
  1420. X    static struct name namebuf[1];    /* One-name buffer */
  1421. X
  1422. X    if (f_sorted_names) {
  1423. X        p = name_next();
  1424. X        if (p) {
  1425. X            namebuf[0].length = strlen(p);
  1426. X            if (namebuf[0].length >= sizeof namebuf[0].name) {
  1427. X                fprintf(stderr, "Argument name too long: %s\n",
  1428. X                    p);
  1429. X                namebuf[0].length = (sizeof namebuf[0].name) - 1;
  1430. X            }
  1431. X            strncpy(namebuf[0].name, p, namebuf[0].length);
  1432. X            namebuf[0].name[ namebuf[0].length ] = 0;
  1433. X            namebuf[0].next = (struct name *)NULL;
  1434. X            namebuf[0].found = 0;
  1435. X            namelist = namebuf;
  1436. X            namelast = namelist;
  1437. X        }
  1438. X        return;
  1439. X    }
  1440. X
  1441. X    /* Non sorted names -- read them all in */
  1442. X    while (NULL != (p = name_next())) {
  1443. X        addname(p);
  1444. X    }
  1445. X}
  1446. X
  1447. X/*
  1448. X * Add a name to the namelist.
  1449. X */
  1450. Xaddname(name)
  1451. X    char    *name;            /* pointer to name */
  1452. X{
  1453. X    register int    i;        /* Length of string */
  1454. X    register struct name    *p;    /* Current struct pointer */
  1455. X
  1456. X    i = strlen(name);
  1457. X    /*NOSTRICT*/
  1458. X    p = (struct name *)
  1459. X        malloc((unsigned)(i + sizeof(struct name) - NAMSIZ));
  1460. X    if (!p) {
  1461. X        fprintf(stderr,"tar: cannot allocate mem for namelist entry\n");
  1462. X        exit(EX_SYSTEM);
  1463. X    }
  1464. X    p->next = (struct name *)NULL;
  1465. X    p->length = i;
  1466. X    strncpy(p->name, name, i);
  1467. X    p->name[i] = '\0';    /* Null term */
  1468. X    p->found = 0;
  1469. X    p->regexp = 0;        /* Assume not a regular expression */
  1470. X    p->firstch = 1;        /* Assume first char is literal */
  1471. X    if (index(name, '*') || index(name, '[') || index(name, '?')) {
  1472. X        p->regexp = 1;    /* No, it's a regexp */
  1473. X        if (name[0] == '*' || name[0] == '[' || name[0] == '?')
  1474. X            p->firstch = 0;        /* Not even 1st char literal */
  1475. X    }
  1476. X
  1477. X    if (namelast) namelast->next = p;
  1478. X    namelast = p;
  1479. X    if (!namelist) namelist = p;
  1480. X}
  1481. X
  1482. X
  1483. X/*
  1484. X * Match a name from an archive, p, with a name from the namelist.
  1485. X */
  1486. Xname_match(p)
  1487. X    register char *p;
  1488. X{
  1489. X    register struct name    *nlp;
  1490. X    register int        len;
  1491. X
  1492. Xagain:
  1493. X    if (0 == (nlp = namelist))    /* Empty namelist is easy */
  1494. X        return 1;
  1495. X    len = strlen(p);
  1496. X    for (; nlp != 0; nlp = nlp->next) {
  1497. X        /* If first chars don't match, quick skip */
  1498. X        if (nlp->firstch && nlp->name[0] != p[0])
  1499. X            continue;
  1500. X
  1501. X        /* Regular expressions */
  1502. X        if (nlp->regexp) {
  1503. X            if (wildmat(p, nlp->name)) {
  1504. X                nlp->found = 1;    /* Remember it matched */
  1505. X                return 1;    /* We got a match */
  1506. X            }
  1507. X            continue;
  1508. X        }
  1509. X
  1510. X        /* Plain Old Strings */
  1511. X        if (nlp->length <= len        /* Archive len >= specified */
  1512. X         && (p[nlp->length] == '\0' || p[nlp->length] == '/')
  1513. X                        /* Full match on file/dirname */
  1514. X         && strncmp(p, nlp->name, nlp->length) == 0) /* Name compare */
  1515. X        {
  1516. X            nlp->found = 1;        /* Remember it matched */
  1517. X            return 1;        /* We got a match */
  1518. X        }
  1519. X    }
  1520. X
  1521. X    /*
  1522. X     * Filename from archive not found in namelist.
  1523. X     * If we have the whole namelist here, just return 0.
  1524. X     * Otherwise, read the next name in and compare it.
  1525. X     * If this was the last name, namelist->found will remain on.
  1526. X     * If not, we loop to compare the newly read name.
  1527. X     */
  1528. X    if (f_sorted_names && namelist->found) {
  1529. X        name_gather();        /* Read one more */
  1530. X        if (!namelist->found) goto again;
  1531. X    }
  1532. X    return 0;
  1533. X}
  1534. X
  1535. X
  1536. X/*
  1537. X * Print the names of things in the namelist that were not matched.
  1538. X */
  1539. Xnames_notfound()
  1540. X{
  1541. X    register struct name    *nlp;
  1542. X    register char        *p;
  1543. X
  1544. X    for (nlp = namelist; nlp != 0; nlp = nlp->next) {
  1545. X        if (!nlp->found) {
  1546. X            fprintf(stderr, "tar: %s not found in archive\n",
  1547. X                nlp->name);
  1548. X        }
  1549. X        /*
  1550. X         * We could free() the list, but the process is about
  1551. X         * to die anyway, so save some CPU time.  Amigas and
  1552. X         * other similarly broken software will need to waste
  1553. X         * the time, though.
  1554. X         */
  1555. X#ifndef unix
  1556. X        if (!f_sorted_names)
  1557. X            free(nlp);
  1558. X#endif
  1559. X    }
  1560. X    namelist = (struct name *)NULL;
  1561. X    namelast = (struct name *)NULL;
  1562. X
  1563. X    if (f_sorted_names) {
  1564. X        while (0 != (p = name_next()))
  1565. X            fprintf(stderr, "tar: %s not found in archive\n", p);
  1566. X    }
  1567. X}
  1568. END_OF_FILE
  1569. if test 11897 -ne `wc -c <'tar.c'`; then
  1570.     echo shar: \"'tar.c'\" unpacked with wrong size!
  1571. fi
  1572. # end of 'tar.c'
  1573. fi
  1574. echo shar: End of archive 2 \(of 5\).
  1575. cp /dev/null ark2isdone
  1576. MISSING=""
  1577. for I in 1 2 3 4 5 ; do
  1578.     if test ! -f ark${I}isdone ; then
  1579.     MISSING="${MISSING} ${I}"
  1580.     fi
  1581. done
  1582. if test "${MISSING}" = "" ; then
  1583.     echo You have unpacked all 5 archives.
  1584.     rm -f ark[1-9]isdone
  1585. else
  1586.     echo You still need to unpack the following archives:
  1587.     echo "        " ${MISSING}
  1588. fi
  1589. ##  End of shell archive.
  1590. exit 0
  1591. -- 
  1592. Mail submissions (sources or binaries) to <amiga@cs.odu.edu>.
  1593. Mail comments to the moderator at <amiga-request@cs.odu.edu>.
  1594. Post requests for sources, and general discussion to comp.sys.amiga.
  1595.